package znet

import (
	"fmt"
	"net"
	"zinx/utils"
	"zinx/ziface"
)

type Connection struct {
	Conn     *net.TCPConn
	ConnID   uint32
	isClosed bool
	ExitChan chan bool
	Router   ziface.IRouter
}

func NewConnection(conn *net.TCPConn, connID uint32, router ziface.IRouter) *Connection {
	c := &Connection{
		Conn:     conn,
		ConnID:   connID,
		isClosed: false,
		Router:   router,
		ExitChan: make(chan bool, 1),
	}
	return c
}

func (c *Connection) StartReader() {
	fmt.Printf("Reader Gorutine is running...\n")
	defer fmt.Printf("connID =%d,Reader is exit,remote addr is %s \n", c.ConnID, c.GetRemoteAddr().String())
	defer c.Stop()

	for {
		buf := make([]byte, utils.GlobalObject.MaxPackageSize)
		_, err := c.Conn.Read(buf)
		if err != nil {
			fmt.Printf("recv buf err ,%s\n", err)
			continue
		}
		//if err := c.handleAPI(c.Conn,buf[:cnt],cnt);err != nil {
		//	fmt.Printf("ConnID =%d,handle is err",c.ConnID)
		//	break
		//}
		req := Request{data: buf, conn: c}
		go func(request ziface.IRequest) {
			c.Router.PreHandle(request)
			c.Router.Handle(request)
			c.Router.PostHandle(request)
		}(&req)
	}
}

func (c *Connection) Start() {
	fmt.Printf("Conn Start()..ConnID = %d \n", c.ConnID)
	go c.StartReader()
}

func (c *Connection) Stop() {
	fmt.Printf("Conn Stop()..ConnID = %d \n", c.ConnID)
	if c.isClosed == true {
		return
	}
	c.isClosed = true
	_ = c.Conn.Close()
	close(c.ExitChan)
}

func (c *Connection) GetTCPConnection() *net.TCPConn {
	return c.Conn
}

func (c *Connection) GetConnId() uint32 {
	return c.ConnID
}

func (c *Connection) GetRemoteAddr() net.Addr {
	return c.Conn.RemoteAddr()
}

func (c *Connection) Send(Data []byte) error {
	return nil
}
